package ajsynchro;

//importsymbol ajsynchro.AJSynchroMethod;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import polyglot.ast.ClassMember;
import polyglot.ast.FieldDecl;
import polyglot.ast.Node;
import polyglot.ext.jl.ast.Node_c;
import polyglot.ext.jl.parse.Name;
import polyglot.ast.NodeFactory;
import polyglot.ast.TypeNode;
import polyglot.types.Flags;
import polyglot.types.TypeSystem;
import polyglot.util.Position;
import polyglot.util.TypedList;

import xaj.xc.ast.NodeXAJ;
import xaj.xc.ast.XAJNodeFactory;

import abc.aspectj.ast.AspectDecl;
import abc.aspectj.ast.AspectDecl_c;
import abc.aspectj.ast.AspectBody;
import abc.aspectj.ast.AspectBody_c;
import abc.aspectj.ast.IntertypeFieldDecl;
import abc.aspectj.ast.PerClause;

public class AJSynchro extends AspectDecl_c implements AspectDecl, NodeXAJ, xaj.lang.Map {


	/*
	@grammar extends aspect_declaration {
		AJSynchro -> "synchronizer" t = name b = AJSynchroBody;
	}*/
	
	public static class AJSynchroBody extends Node_c /*AspectBody_c*/ implements /*AspectBody,*/ NodeXAJ, xaj.lang.Map {
		/*
		@grammar using AJSynchroMethod {
			AJSynchroBody -> "{" a = {AJSynchroBodyMembers} "}";
			AJSynchroBodyMembers -> m = class_member_declaration
								| 
								  asm = AJSynchroMethod;
		}*/
		
		private Map map;
		/*
		public AJSynchroBody(Position pos) {
			this(pos, new TypedList(new LinkedList(), ClassMember.class, false));
		}
		
		private AJSynchroBody(Position pos, List members) {
			super(pos, members);
			this.map = new HashMap();
			System.out.println("Criou um objeto AJSynchroBody");
		}*/
		
		public AJSynchroBody(Position pos) {
			super(pos);
			this.map = new HashMap();
			System.out.println("Criou um objeto AJSynchroBody");
		}
		
		public Object get(String name) {
			return map.get(name);
		}

		public boolean add(String name, Object value) {
			if (!map.containsKey(name)) {
				map.put(name, value);
				return true;
			} else
				return false;
		}

		public Iterator iterator() {
			return map.keySet().iterator();
		}

		public void set(String name, Object value) {
			if (map.containsKey(name)) {
				map.keySet();
				map.put(name, value);
			}
		}
		//---------------------------------------------------------
		private static TypeNode nameClass;
		
		public static TypeNode getClassHost() {
			return nameClass;
		}
		
		public static void setClassHost(TypeNode name) {
			nameClass = name;
		}
		
		public Node desugar(NodeFactory ft, TypeSystem ts) {
			XAJNodeFactory nf = (XAJNodeFactory) ft;
			xaj.lang.List l = (xaj.lang.List) get("a");
						
			List members = new TypedList(new LinkedList(), ClassMember.class, false);
			Iterator it = l.iterator();
			ClassMember c;
			while(it.hasNext()) {
				xaj.lang.Map map = (xaj.lang.Map) it.next();
				c = (ClassMember) map.get("m");
				if(c != null) {
					if(c instanceof FieldDecl) {
						FieldDecl field = (FieldDecl) c;
						IntertypeFieldDecl inter = nf.IntertypeFieldDecl(c.position(),
								field.flags(), field.type(), nameClass, field.name(),
								field.init());
						members.add(inter);
					}
				} else {
					c = (ClassMember) map.get("asm");
					members.add(((AJSynchroMethod) c).desugar(ft, ts));
				}
				
			}
			AspectBody b = nf.AspectBody(position(), members);			
			return b;
		}
	}

	private Map map;
	
	public AJSynchro(Position pos) {
		this(pos, false, null, null, null, new TypedList(new LinkedList(),
				TypeNode.class, false), null, null);
	}
	
	private AJSynchro(Position pos, boolean isPrivileged, Flags flags,
			String name, TypeNode superClass, List interfaces, PerClause per,
			AspectBody body) {
		super(pos, isPrivileged, flags, name, superClass, interfaces, per, body);
		this.map = new HashMap();
		System.out.println("Criou um objeto AJSynchro");
	}

	public Object get(String name) {
		return map.get(name);
	}

	public boolean add(String name, Object value) {
		if (!map.containsKey(name)) {
			map.put(name, value);
			return true;
		} else
			return false;
	}

	public Iterator iterator() {
		return map.keySet().iterator();
	}

	public void set(String name, Object value) {
		if (map.containsKey(name)) {
			map.keySet();
			map.put(name, value);
		}
	}

	public Node desugar(NodeFactory ft, TypeSystem ts) {
		XAJNodeFactory nf = (XAJNodeFactory) ft;
		//get parametres
		Name name = (Name) get("t");
		AJSynchroBody body = (AJSynchroBody) get("b");
		
		AJSynchroMethod.setClassHost(name.toString());
		AJSynchroBody.setClassHost(name.toType());
		AspectBody b = (AspectBody) body.desugar(ft, ts);
				
		AspectDecl a = nf.AspectDecl(position(), false, Flags.NONE, "AJSynchro" + 
				name.toString(), null, new TypedList(new LinkedList(),
						TypeNode.class, false), null, b);		
		return a;
	}
}